package com.jpro.module.system.job;

import com.jpro.framework.quartz.client.constant.ExecutorBlockStrategyEnum;
import com.jpro.framework.quartz.client.constant.ExecutorRouteStrategyEnum;
import com.jpro.framework.quartz.client.util.ScheduleUtil;
import com.jpro.framework.quartz.client.vo.JobInfo;
import com.jpro.framework.tenant.core.context.TenantContextHolder;
import com.jpro.module.system.cache.CacheService;
import com.jpro.module.system.dal.dataobject.user.AdminUserDO;
import com.jpro.module.system.enums.user.EnumUserStatus;
import com.jpro.module.system.job.util.XxlJobUtil;
import com.jpro.module.system.service.user.AdminUserService;
import com.jprocms.module.cms.enums.EnumJobStatus;
import com.jprocms.module.cms.enums.EnumJobType;
import com.jprocms.module.cms.enums.EnumXxlJobTriggerStatus;
import com.jprocms.module.cms.util.CronUtil;
import com.jprocms.module.cms.vo.JobCreateReqVO;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

import static com.jpro.module.system.dal.redis.RedisKeyConstants.LOGIN_ERROR_USER;
import static com.jprocms.module.cms.constant.JobConstant.JOB_HANDLER_USER_UNLOCK;

@Slf4j
@Service
public class SystemJobServiceImpl implements SystemJobService {

    @Resource
    private AdminUserService adminUserService;
    @Resource
    private CacheService cacheService;

    @Override
    public void createEnableUserJob(Long userId, Date jobTime) {
        JobCreateReqVO job = new JobCreateReqVO();
        job.setJobName(String.format("解锁用户ID:%s", userId));
        job.setJobType(EnumJobType.UNLOCK_USER.getCode().shortValue());
        job.setDataId(userId);
        job.setStatus(EnumJobStatus.RUNABLE.getCode());
        job.setParams(userId.toString());
        job.setCron(CronUtil.date2Cron(jobTime, CronUtil.CRON_DATE));
        job.setJobHandler(JOB_HANDLER_USER_UNLOCK);
        job.setId(userId);
        Integer xxlJobId = addJobToXxlJobServer(job, true);
        log.info("创建用户解锁任务成功，任务ID：{}", xxlJobId);
    }

    @XxlJob(JOB_HANDLER_USER_UNLOCK)
    public void userUnlock() {
        String param = XxlJobUtil.getBussinessParam();
        log.info("用户解锁，参数：{}", param);
        if (!StringUtils.isNumeric(param)) {
            log.error("用户解锁任务：{} 错误，定时任务执行失败", param);
            return;
        }
        Long userId = Long.valueOf(param);
        //定时任务这里查询数据忽略租户条件
        TenantContextHolder.setIgnore(true);
        final AdminUserDO user = adminUserService.getUser(userId);
        if (user == null) {
            log.error("id为：{}不存在，定时任务执行失败", userId);
            return;
        }
        //执行更改用户状态
        adminUserService.updateUserStatus(userId, EnumUserStatus.ENABLE.getStatus());
        //执行完成后删除
        ScheduleUtil.deleteJob(XxlJobHelper.getJobId());
        //清理登录错误次数的缓存 否则还会进入错误次数检查判断又禁用了
        String cacheKey = LOGIN_ERROR_USER + ":" + userId;
        cacheService.deleteObject(cacheKey);
    }

    /**
     * 请求xxl 创建 定时任务
     *
     * @param job      job信息
     * @param isRunJob
     * @return
     */
    private Integer addJobToXxlJobServer(JobCreateReqVO job, boolean isRunJob) {
        JobInfo jobInfo = new JobInfo();
        EnumXxlJobTriggerStatus executorRouteStrategyEnum = isRunJob ?
                EnumXxlJobTriggerStatus.RUNNING :
                EnumXxlJobTriggerStatus.STOP;
        jobInfo.setJobCron(job.getCron());
        jobInfo.setExecutorHandler(job.getJobHandler());
        jobInfo.setExecutorBlockStrategyEnum(ExecutorBlockStrategyEnum.DISCARD_LATER.name());
        jobInfo.setExecutorRouteStrategyEnum(ExecutorRouteStrategyEnum.LEAST_FREQUENTLY_USED.name());
        jobInfo.setTriggerStatus(executorRouteStrategyEnum.getCode());
        jobInfo.setExecutorParam(XxlJobUtil.parseToXxlParam(job.getId(), job.getParams()));
        jobInfo.setJobDesc(job.getJobName());
        return ScheduleUtil.addJob(jobInfo);
    }


}
